package io.renren.utils.ali;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import io.renren.common.exception.RenException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chenlei
 */
@Component
public class AliPayUtils implements ThirdAuth {

    private static Logger LOGGER = LoggerFactory.getLogger(AliPayUtils.class);

    @Autowired
    AliPayProperties aliPayProperties;


    AlipayClient alipayClient = null;


    /**
     * 获取支付宝授权链接
     *
     * @return
     */
    @Override
    public String authenticate() {
        String targetId = RandomUtil.randomString(3) + "_" + System.currentTimeMillis();
        String content = "apiname=com.alipay.account.auth&app_id=" + aliPayProperties.getAppId()
                + "&app_name=mc&auth_type=AUTHACCOUNT&biz_type=openservice&method=alipay.open.auth.sdk.code.get"
                + "&pid=" + aliPayProperties.getUid() + "&product_id=APP_FAST_LOGIN&scope=kuaijie&target_id=" + targetId + "&sign_type=RSA2";
        try {
            String sign = AlipaySignature.rsaSign(content, aliPayProperties.getPrivateKey(), "UTF-8", "RSA2");
            String enCodesign = URLEncoder.encode(sign, "UTF-8");
            content = content + "sign=" + sign + enCodesign;
        } catch (AlipayApiException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return content;
    }

    /**
     * 根据用户授权码获取用户access_token
     *
     * @param authCode
     * @return
     * @throws AlipayApiException
     */
    public String getAccessToken(String authCode) throws AlipayApiException {
        if (alipayClient == null) {
            initAlipayClient();
        }
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(authCode);
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
        LOGGER.info("accessToken = {}", response.getAccessToken());
        LOGGER.info("aliPayUserId = {}", response.getAlipayUserId());
        LOGGER.info("authTokenType = {}", response.getAuthTokenType());
        LOGGER.info("expireIn = {}", response.getExpiresIn());
        LOGGER.info("userId = {}", response.getUserId());
        LOGGER.info("refreshToken = {}", response.getRefreshToken());

        if (response.isSuccess()) {
            LOGGER.info(response.getAccessToken());
            return response.getAccessToken();
        } else {
            LOGGER.info("调用失败");
            throw new RenException("获取支付宝用户信息失败");
        }
    }



    /**
     * 根据用户accessToken获取用户信息
     *
     * @param accessToken
     * @throws AlipayApiException
     */
    public Map<String, String> getUserInfo(String accessToken) throws AlipayApiException {
        if (alipayClient == null) {
            initAlipayClient();
        }
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
        if (response.isSuccess()) {
            // 获取成功
            Map<String, String> map = new HashMap<>();
            LOGGER.info("获取成功");
            LOGGER.info("response = {}", response);
            Object o = JSON.toJSON(request);
            LOGGER.info("response.toJson = {}", o);
            LOGGER.info("response.userId = {}", response.getUserId());
            String nickName = response.getNickName();
            LOGGER.info("nickName = {}", nickName);
            LOGGER.info("userId = {}", response.getUserId());
            LOGGER.info("headPhoto = {}", response.getAvatar());
            LOGGER.info("mobile = {}", response.getMobile());

            map.put("nickName", nickName);
            map.put("userId", response.getUserId());
            map.put("mobile", response.getMobile());
            map.put("headPhoto", response.getAvatar());
            return map;
        } else {
            LOGGER.info("获取失败");
            throw new RenException("获取用户失败");
        }
    }


    /**
     * 生成支付宝订单信息
     *
     * @param goodsName
     * @param price
     * @param orderNo
     * @return
     */
    @Override
    public Object generateOrderStr(String goodsName, String price, String orderNo) {
        LOGGER.info("生成支付宝订单信息参数 goodsName = {},price = {}, orderNo = {}", goodsName, price, orderNo);
        //实例化客户端
        if (alipayClient == null) {
            initAlipayClient();
        }

        String orderString = "";
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("好生活支付宝支付订单");
        model.setSubject(goodsName);
        model.setOutTradeNo(orderNo);
        model.setTimeoutExpress("15m");
        model.setTotalAmount(price);
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl("http://118.190.175.235/renren-fast/app/order/aliCallBack");
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            //就是orderString 可以直接给客户端请求，无需再做处理。
            orderString = response.getBody();
            LOGGER.info(response.getBody());
        } catch (AlipayApiException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return orderString;
    }


    private void initAlipayClient() {
        alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliPayProperties.getAppId(),
                aliPayProperties.getPrivateKey(), "json", "UTF-8", aliPayProperties.getAliPayPublicKey(), "RSA2");
    }

//    /**
//     * 支付宝退款
//     *
//     * @param orderEntity 退款订单
//     * @return
//     */
//    public R refund(OrderEntity orderEntity) {
//        LOGGER.info("[支付宝退款订单信息 orderEntity - {}]", orderEntity);
//        if (alipayClient == null) {
//            initAlipayClient();
//        }
//        Long appUserId = orderEntity.getAppUserId();
//        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
//        String bizContent = "{" +
//                "\"out_trade_no\":\"" + orderEntity.getOrderNo() + "\"," +
//                "\"refund_amount\":" + orderEntity.getPayPrice() + "," +
//                "\"refund_currency\":\"CNY\"," +
//                "\"refund_reason\":\"正常退款\"," +
//                "      \"goods_detail\":[{" +
//                "        \"goods_id\":\"" + orderEntity.getGoodsId() + "\"," +
//                "\"alipay_goods_id\":\"20010001\"," +
//                "\"goods_name\":\"" + orderEntity.getGoodsName() + "\"," +
//                "\"quantity\":1," +
//                "\"price\":" + orderEntity.getGoodsPrice() +
//                "        }]" +
//                "  }";
//
//        LOGGER.info(" bizContent = {}", bizContent);
//        request.setBizContent(bizContent);
//        AlipayTradeRefundResponse response;
//        try {
//            response = alipayClient.execute(request);
//            LOGGER.info("response.getTradeNo = {} ", response.getTradeNo());
//            LOGGER.info("response.getOutTradeNo = {} ", response.getOutTradeNo());
//            LOGGER.info("response.getBuyerUserId = {} ", response.getBuyerUserId());
//            LOGGER.info("response.getRefundFee = {} ", response.getRefundFee());
//            LOGGER.info("response.toString = {} ", response.toString());
//            if (response.isSuccess()) {
//                LOGGER.info("调用成功，退款成功");
//                return R.ok();
//            } else {
//                LOGGER.info("调用失败，退款失败");
//                return R.error("支付宝退款失败");
//            }
//        } catch (Exception e) {
//            LOGGER.info("-----出现异常：{}", e.getMessage());
//            LOGGER.error(e.getMessage(), e);
//            return R.error("支付宝退款失败");
//        }
//    }
}
